package com.ebiz.mockup.view
{
	import com.ebiz.mockup.component.BoardCell;
	import com.ebiz.mockup.component.BoardJoint2;
	import com.ebiz.mockup.component.BoardJoint3;
	import com.ebiz.mockup.component.BoardJointBase;
	import com.ebiz.mockup.component.IBoardJoint;
	import com.ebiz.mockup.core.Core;
	import com.ebiz.mockup.core.Warm;
	import com.ebiz.mockup.frameworkExtends.pureMVC.AbstractMediator;
	import com.ebiz.mockup.messages.AddComponentInBoardMSG;
	import com.ebiz.mockup.messages.BoardCellMouseDownMSG;
	import com.ebiz.mockup.messages.SelectCellMSG;
	import com.ebiz.mockup.messages.ToolsMenuMSG;
	import com.ebiz.mockup.proxies.SelectedCelsProxy;
	import com.ebiz.mockup.utils.CheckUtils;
	import com.ebiz.mockup.valueobjct.CellVO;
	
	import flash.events.MouseEvent;
	
	import org.puremvc.as3.multicore.interfaces.INotification;
	
	public class BoardMediator extends AbstractMediator
	{
		public static const NAME:String = "BoardMediator";
		
		private var currentState:String = "none";//dragging //  join
		private var currentType:String = "";//transition fork join
		
		private var origiMouseX:Number;
		private var origiMouseY:Number;
		private var proxy:SelectedCelsProxy = SelectedCelsProxy.instance;
		
		private function get view():Board{
			return this.viewComponent as Board
		}
		
		public function BoardMediator(viewComponent:Object=null)
		{
			super(NAME, viewComponent);
			this.notificationInterests = [
				AddComponentInBoardMSG.ADD_A_COMPONENT,
				BoardCellMouseDownMSG.BOARD_CELL_MOUSE_DOWN,
				SelectCellMSG.SELECT_LIST_COMPONENT_AND_PREPARE_ADD,
				ToolsMenuMSG.BOARD_CELL_BUILD_MULTI_JOINT,
				ToolsMenuMSG.BOARD_CELL_LAYER_BOTTOM,
				ToolsMenuMSG.BOARD_CELL_LAYER_DOWN,
				ToolsMenuMSG.BOARD_CELL_LAYER_TOP,
				ToolsMenuMSG.BOARD_CELL_LAYER_UP,
				ToolsMenuMSG.BOARD_CELL_START_BUILD_JOINT,
				ToolsMenuMSG.BOARD_CELL_REMOVE_JOINT,
				ToolsMenuMSG.BOARD_CELL_REMOVE_CELLS
			];
		}
		
		override public function onRegister():void{
			super.onRegister();
			//
			this.view.addEventListener(MouseEvent.MOUSE_DOWN,view_mouseDownHandler);
			this.view.background.addEventListener(MouseEvent.MOUSE_DOWN,backgroud_mouseDownHandler);
			this.view.addEventListener(MouseEvent.MOUSE_UP,view_mouseUpHandler);
			this.view.addEventListener(MouseEvent.MOUSE_MOVE,view_mouseMoveHandler);
			this.view.addEventListener(MouseEvent.MOUSE_OUT,view_mouseOutHandler);
		}
		
		override public function onRemove():void{
			super.onRemove();
			this.view.background.removeEventListener(MouseEvent.MOUSE_DOWN,view_mouseDownHandler);
		}
		
		override public function handleNotification(notification:INotification):void{
			var i:int;
			var len:int;
			var $cell:BoardCell;
			switch(notification.getName()){
				case SelectCellMSG.SELECT_LIST_COMPONENT_AND_PREPARE_ADD:
					var $msg:SelectCellMSG = notification.getBody() as SelectCellMSG;
					this.stopAllCellsSelected();
					this.stopStateDragging();
					this.stopJoin();
					if($msg.type == "component"){
					}else if($msg.type == "select"){
						this.stopSelectRim();
						this.stopPrepareAddCell()
					}else if($msg.type == "join3"){
//						if($msg.data.name=="Fork"){
//							join3Cells("Fork");	
//						}else{
//							join3Cells("Join");	
//						}
						beginJoin3($msg.data.name);
					}else if($msg.type == "join2"){
						beginJoin2();
					}
//					this.currentState == SelectCellMSG.SELECT_LIST_CELL_AND_PREPARE_ADD;
					break;
				case AddComponentInBoardMSG.ADD_A_COMPONENT:
					$cell = new BoardCell();
					var $vo:CellVO;
					$vo = new CellVO;
					$vo.image = Core.instance.dragging.iconBig;
					$vo.name = Core.instance.dragging.name;
					$cell.vo = $vo;
					$cell.x = (notification.getBody() as AddComponentInBoardMSG).x;
					$cell.y = (notification.getBody() as AddComponentInBoardMSG).y;
					$cell.addToContainer(this.view.cellContainer);
					$cell.selected = true;
					this.stopPrepareAddCell();
					break;
				case BoardCellMouseDownMSG.BOARD_CELL_MOUSE_DOWN:
					var $e:MouseEvent = (notification.getBody() as BoardCellMouseDownMSG).event
					var $cellOperating:BoardCell = $e.currentTarget as BoardCell;
					if(this.currentState == "join"){
						this.pushCellInJoin($cellOperating);
						return;
					}
					if(Core.instance.dragging!=null){
						return;
					}
					var $isPrepareDrag:Boolean = true;
					if($cellOperating.selected){
						if($e.shiftKey){
							$cellOperating.selected = false;
							$isPrepareDrag = false;
							
						}
					}else{
						if(!$e.shiftKey){
							this.stopAllCellsSelected();
						}
						$cellOperating.selected = true;
					}
					if($isPrepareDrag){
						this.prepareDrag();
					}
					break;
				case ToolsMenuMSG.BOARD_CELL_BUILD_MULTI_JOINT:
					switch(SelectedCelsProxy.instance.cellLength){
						case 2:
							this.join2Cells();
							break;
						case 3:
//							this.join3Cells();
							break;
					}
					break;
				case ToolsMenuMSG.BOARD_CELL_START_BUILD_JOINT:
					break;
				case ToolsMenuMSG.BOARD_CELL_REMOVE_CELLS:
					this.removeSelectedCells();
					this.stopPrepareAddCell();
					this.stopSelectRim();
					this.stopJoin();
					this.stopStateDragging();
					break;
				case ToolsMenuMSG.BOARD_CELL_REMOVE_JOINT:
					this.stopPrepareAddCell();
					this.stopSelectRim();
					this.stopJoin();
					this.stopStateDragging();
					if(proxy.cellLength<2){
						Warm.instance.show(Warm.LEASE_CELLS_TO_REMOVE_JOINT);
						return;
					}
					if(proxy.cellLength>3){
						Warm.instance.show(Warm.MORE_CELLS_TO_REMOVE_JOINT);
						return;
					}
					if(!proxy.hasJointInCells){
						Warm.instance.show(Warm.NO_JOINT_IN_CELLS_TO_REMOVE_JOINT);
						return;
					}
					this.removeJoint(notification.getBody() as IBoardJoint);
					break;
				case ToolsMenuMSG.BOARD_CELL_LAYER_BOTTOM:
					this.stopPrepareAddCell();
					this.stopSelectRim();
					this.stopJoin();
					this.stopStateDragging();
					if(proxy.cellLength==0){
						Warm.instance.show(Warm.NO_CELLS_SELECTED);
						return;
					}
					len = this.view.cellContainer.numElements;
					var $bottomCellLength:int = 0;
					for(i=0;i<len;i++){
						$cell = this.view.cellContainer.getElementAt(i) as BoardCell;
						if($cell.selected){
							if(i!=$bottomCellLength){
								this.view.cellContainer.addElementAt($cell,$bottomCellLength);
							}
							$bottomCellLength++;
						}
					}
					break;
				case ToolsMenuMSG.BOARD_CELL_LAYER_DOWN:
					this.stopPrepareAddCell();
					this.stopSelectRim();
					this.stopJoin();
					this.stopStateDragging();
					if(proxy.cellLength==0){
						Warm.instance.show(Warm.NO_CELLS_SELECTED);
						return;
					}
					len = this.view.cellContainer.numElements;
					for(i=1;i<len;i++){
						$cell = this.view.cellContainer.getElementAt(i) as BoardCell;
						var $downCell:BoardCell = this.view.cellContainer.getElementAt(i-1) as BoardCell;
						if(!$downCell.selected){
							if($cell.selected){
								this.view.cellContainer.addElementAt($cell,i-1);
							}
						}
					}
					break;
				case ToolsMenuMSG.BOARD_CELL_LAYER_TOP:
					this.stopPrepareAddCell();
					this.stopSelectRim();
					this.stopJoin();
					this.stopStateDragging();
					if(proxy.cellLength==0){
						Warm.instance.show(Warm.NO_CELLS_SELECTED);
						return;
					}
					len = this.view.cellContainer.numElements;
					var $topCellLength:int = len-1;
					for(i=len-1;i>=0;i--){
						$cell = this.view.cellContainer.getElementAt(i) as BoardCell;
						if($cell.selected){
							if(i!=$topCellLength){
								this.view.cellContainer.addElementAt($cell,$topCellLength);
							}
							$topCellLength--;
						}
					}
					break;
				case ToolsMenuMSG.BOARD_CELL_LAYER_UP:
					this.stopPrepareAddCell();
					this.stopSelectRim();
					this.stopJoin();
					this.stopStateDragging();
					if(proxy.cellLength==0){
						Warm.instance.show(Warm.NO_CELLS_SELECTED);
						return;
					}
					len = this.view.cellContainer.numElements;
					for(i=len-2;i>=0;i--){
						$cell = this.view.cellContainer.getElementAt(i) as BoardCell;
						var $upCell:BoardCell = this.view.cellContainer.getElementAt(i+1) as BoardCell;
						if(!$upCell.selected){
							if($cell.selected){
								this.view.cellContainer.addElementAt($cell,i+1);
							}
						}
					}
					break;
			}
		}
		
		private function prepareAddComponent():void{
			var $msg:AddComponentInBoardMSG = new AddComponentInBoardMSG();
			$msg.x = this.view.mouseX;
			$msg.y = this.view.mouseY;
			this.facade.sendNotification(AddComponentInBoardMSG.ADD_A_COMPONENT,$msg);
		}
		
		private function countSelectedRimCells():void{
			var i:int;
			var len:int;
			len = this.view.cellContainer.numElements;
			for(i=0;i<len;i++){
				var $cell:BoardCell = (this.view.cellContainer.getElementAt(i) as BoardCell);
				if(!$cell.selected){
					if($cell.x>=this.view.selectRim.startX && $cell.x<=this.view.selectRim.endX){
						if($cell.y>=this.view.selectRim.startY && $cell.y<=this.view.selectRim.endY){
							$cell.selected = true;
						}
					}
				}
			}
		}
		
		
		//==clear and cancel
		private function stopInterface():void{
			this.stopAllCellsSelected();
			this.stopSelectRim();
			this.stopStateDragging();
			this.stopPrepareAddCell();
			this.stopJoin();
		}
		private function stopAllCellsSelected():void{
			var i:int;
			var len:int;
			len = this.view.cellContainer.numElements;
			for(i=0;i<len;i++){
				var $cell:BoardCell = (this.view.cellContainer.getElementAt(i) as BoardCell);
				if($cell.selected){
					$cell.selected = false;
				}
			}
		}
		private function stopStateDragging():void{
			if(this.currentState=="dragging"){
				this.currentState = "none";
			}
		}
		private function stopSelectRim():void{
			this.view.selectRim.hide();
		}
		private function stopPrepareAddCell():void{
			this.facade.sendNotification(AddComponentInBoardMSG.STOP_PREPARE_ADD_A_COMPONENT);
		}
		private function stopJoin():void{
			if(this.currentJoin){
				this.currentJoin.dispose();
				this.currentJoin = null;
			}
			if(this.currentState=="join"){
				this.currentState = "none";
			}
		}
		/**
		 * 
		 * @return 
		 * 
		 */		
		private function doneSelectRim():void{
			if(this.view.selectRim.visible){
				this.countSelectedRimCells();
				this.view.selectRim.hide();
			}
		}
	
		/**
		 *public tools 
		 * 
		 */		
		private function join2Cells():void{
			if(SelectedCelsProxy.instance.cellLength!=2){
				Warm.instance.show(Warm.NEED_2_CELLS);
				return;
			}
			var $joint:IBoardJoint; 
			var $cell0:BoardCell = (SelectedCelsProxy.instance.cells[0] as BoardCell);
			var $cell1:BoardCell = (SelectedCelsProxy.instance.cells[1] as BoardCell);
			$joint = CheckUtils.getJointBetweenCells($cell0,$cell1);
			if($joint is BoardJoint2){
				$joint.switchCells();
			}else{
				if($joint!=null){
					this.removeJoint($joint);
				}
				$joint = new BoardJoint2();
				$joint.setCells($cell0,$cell1);
				$joint.addToContainer(this.view.jointContainer);
				SelectedCelsProxy.instance.checkJoint();
			}
		}
		private function join3Cells($kind:String):void{
			if(SelectedCelsProxy.instance.cellLength!=3){
				Warm.instance.show(Warm.NEED_3_CELLS);
				return;
			}
			var $$cell0:BoardCell = (SelectedCelsProxy.instance.cells[0] as BoardCell);
			var $$cell1:BoardCell = (SelectedCelsProxy.instance.cells[1] as BoardCell);
			var $$cell2:BoardCell = (SelectedCelsProxy.instance.cells[2] as BoardCell);
			/*if($kind == "Fork"){
				
			}else{
				//Join
				
			}*/
			//
			var $arr:Array = [$$cell0,$$cell1,$$cell2];
			$arr.sortOn("y");
			var $cell0:BoardCell;
			var $cell1:BoardCell;
			var $cell2:BoardCell;
			$cell0 = $arr[1];
			$cell1 = $arr[0];
			$cell2 = $arr[2];
			//
			var $joint:IBoardJoint;
			$joint = CheckUtils.getJointAmongCells($cell0,$cell1,$cell2);
			if($joint!=null){
				$joint.switchCells();
			}else{
				checkAndRemoveJointInCells($cell0,$cell1,$cell2);
				$joint= new BoardJoint3();
				$joint.setCells($cell0,$cell1,$cell2);
				$joint.addToContainer(this.view.jointContainer);
				SelectedCelsProxy.instance.checkJoint();
			}
		}
		public function checkAndRemoveJointInCells($cell0:BoardCell,$cell1:BoardCell,$cell2:BoardCell):void{
			this.checkAndRemoveJointBetweenCells($cell0,$cell1);
			this.checkAndRemoveJointBetweenCells($cell1,$cell2);
			this.checkAndRemoveJointBetweenCells($cell0,$cell2);
		}
		
		private function checkAndRemoveJointBetweenCells($cell0:BoardCell,$cell1:BoardCell):void{
			var $joint:IBoardJoint;
			$joint = CheckUtils.getJointBetweenCells($cell0,$cell1);
			if($joint!=null){
				this.removeJoint($joint);
			}
		}
		private function removeJoint($joint:IBoardJoint):void{
			$joint.dispose();
			SelectedCelsProxy.instance.checkJoint();
		}
		private function removeSelectedCells():void{
			if(SelectedCelsProxy.instance.cellLength==0){
				Warm.instance.show(Warm.NO_CELLS_TO_BE_REMOVE);
				return;
			}
			var $cell:BoardCell;
			while(SelectedCelsProxy.instance.cellLength){
				$cell = SelectedCelsProxy.instance.cells[0] as BoardCell;
				$cell.dispose();
			}
		}
		//joint begin 
		private var currentJoin:BoardJointBase;
		private function beginJoin2():void{
			if(this.view.cellContainer.numElements<2){
				Warm.instance.show(Warm.STAGE_NEED_2_CELLS);
				this.stopPrepareAddCell();
			}else{
				Warm.instance.show(Warm.PLEASE_SELECT_FIRST_CELL);
				this.currentState = "join";
				this.currentType = "transition";
			}
		}
		private function beginJoin3($type:String):void{
			if(this.view.cellContainer.numElements<3){
				Warm.instance.show(Warm.STAGE_NEED_3_CELLS);
				this.stopPrepareAddCell();
			}else{
				Warm.instance.show(Warm.PLEASE_SELECT_FIRST_CELL);
				this.currentState = "join";
				if($type=="Fork"){
					this.currentType = "fork";
				}else if($type=="Join"){
					this.currentType = "join";
				}
				
			}
		}
		private function pushCellInJoin($cell:BoardCell):void{
			if(this.currentJoin==null){
				$cell.selected = true;
				var $joint:BoardJointBase;
				if(this.currentType=="transition"){
					$joint = new BoardJoint2();
					Warm.instance.show(Warm.PLEASE_SELECT_OTHER_CELL);
				}else{
					$joint = new BoardJoint3();
					$joint.type = this.currentType;
					Warm.instance.show(Warm.PLEASE_SELECT_SECOND_CELL);
				}
				this.currentJoin = $joint;
				$joint.pushCell($cell);
				$joint.addToContainer(this.view.jointContainer);
				SelectedCelsProxy.instance.checkJoint();
			}else{
				if(this.currentJoin.pushCell($cell)){
					if(this.currentType=="fork" || this.currentType=="join"){
						$cell.selected = true;
						if(this.currentType=="fork"){
							this.currentType = "fork2";
						}
						if(this.currentType=="join"){
							this.currentType = "join2";
						}
					}else if(this.currentType=="fork2" || this.currentType=="join2"){
						$cell.selected = true;
						this.currentJoin = null;
						this.currentState = "dragging";
						stopPrepareAddCell();
						this.prepareDrag();
						SelectedCelsProxy.instance.checkJoint();
					}else if(this.currentType=="transition"){
						$cell.selected = true;
						this.currentJoin = null;
						this.currentState = "dragging";
						stopPrepareAddCell();
						this.prepareDrag();
						SelectedCelsProxy.instance.checkJoint();
					}
				}else{
				}
			}
		}
		private function prepareDrag():void{
			var i:int;
			var len:int = this.view.cellContainer.numElements;
			for(i=0;i<len;i++){
				(this.view.cellContainer.getElementAt(i) as BoardCell).saveOrigiCoor();
			}
			this.currentState = "dragging";
			this.origiMouseX = this.view.mouseX;
			this.origiMouseY = this.view.mouseY;
		}
		//==handler
		private function backgroud_mouseDownHandler(event:MouseEvent):void{
			if(event.shiftKey){
			}else{
				if(this.currentState == "join"){
					return;
				}
				this.stopAllCellsSelected();
			}
			this.view.selectRim.setStartPoint(this.view.mouseX,this.view.mouseY);
		}
		
		private function view_mouseDownHandler(event:MouseEvent):void
		{
			if(Core.instance.dragging!=null){
				if(this.currentState == "join"){
					
				}else if(this.currentState == "none"){
					this.prepareAddComponent();
				}
			}
			
		}
		
		private function view_mouseUpHandler(event:MouseEvent):void{
			if(Core.instance.draggingAlwaysMouseDown){
				this.prepareAddComponent();
			}
			this.stopStateDragging();
			this.doneSelectRim();
		}	
		
		private function view_mouseMoveHandler(event:MouseEvent):void{
			var i:int;
			var len:int;
			if(event.buttonDown){
				if(this.currentState == "dragging"){
					len = this.view.cellContainer.numElements;
					for(i=0;i<len;i++){
						var $cell:BoardCell = (this.view.cellContainer.getElementAt(i) as BoardCell);
						if($cell.selected){
							$cell.dragChangeRange(this.view.mouseX - this.origiMouseX,this.view.mouseY - this.origiMouseY);
						}
					}
				}
				if(this.view.selectRim.visible){
					this.view.selectRim.setEndPoint(this.view.mouseX,this.view.mouseY);
				}
			}else{
				this.stopStateDragging();
				this.doneSelectRim();
			}
			if(this.currentState == "join"){
				if(this.currentJoin!=null){
					this.currentJoin.updateMouseXY(this.view.mouseX,this.view.mouseY);
				}
			}
		}
		
		private function view_mouseOutHandler(event:MouseEvent):void{
			if(this.view.mouseX>=this.view.x &&this.view.mouseX<=this.view.width){
				if(this.view.mouseY>=this.view.y && this.view.mouseY<=this.view.height){
					//in !
					return;
				}
			}
		}
	}
}